const WebScorket = require("ws");
const os = require("os");
const fs = require("fs");

function getNetworkInterfaces() {
  const interfaces = os.networkInterfaces();
  for (const ifaceKey in interfaces) {
    const interfacesArray = interfaces[ifaceKey];
    interfacesArray.forEach(function (interface) {
      if (interface.family === "IPv4" && !interface.internal) {
        console.log(`Interface: ${ifaceKey}`);
        console.log(`IP Address: ${interface.address}`);
      }
    });
  }
}

getNetworkInterfaces();

const api_result = {
  ping: 0,
  get_chip_info: {
    cpu: "ESP32S3",
    flash: 16 * 1024 * 1024,
    ram: 210 * 1024,
    psram: 8 * 1024 * 1024,
    mac: "D4:DA:21:DC:8D:A2",
    version: "v1.0",
    "api version": "v1.0",
    io: 40,
  },
  wifi_scan: [
    {
      ssid: "TTG-MI4A",
      rssi: -50,
    },
    {
      ssid: "TTG_WIFI",
      rssi: -55,
    },
    {
      ssid: "TTG-CMCC",
      rssi: -65,
    },
    {
      ssid: "TTG-192.168.2.1",
      rssi: -35,
    },
  ],
  get_config_io: {
    wakeup: [{ enable: true, uart: [false, false, false], gpio: [0] }],
    uart: [
      {
        enable: true,
        Buffer: 4096,
        io_map: { TX: 17, RX: 18, RST: 11, CTS: -1 },
      },
      {
        enable: false,
        Buffer: 4096,
        io_map: { TX: -1, RX: -1, RST: -1, CTS: -1 },
      },
      {
        enable: false,
        Buffer: 4096,
        io_map: { TX: -1, RX: -1, RST: -1, CTS: -1 },
      },
    ],
    i2c: [
      {
        enable: false,
        Buffer: 4096,
        io_map: { SDA: -1, SCL: -1, RST: -1, INT: -1 },
      },
      {
        enable: false,
        Buffer: 4096,
        io_map: { SDA: -1, SCL: -1, RST: -1, INT: -1 },
      },
    ],
    adc: [{ enable: false, Buffer: 4096, gpio: [-1] }],
    pwm: [{ enable: false, Frequency: 10000, Bits: 8, gpio: [-1] }],
    spi: [
      {
        enable: false,
        mode: 0,
        Buffer: 4096,
        io_map: { SDA: -1, SCL: -1, CS: -1, DC: -1, INT: -1, RST: -1 },
      },
    ],
    sdcard: [
      {
        enable: false,
        io_map: { CLK: -1, CMD: -1, D0: -1, D1: -1, D2: -1, D3: -1 },
      },
    ],
    dap: [
      { enable: true, Buffer: 4096, io_map: { SWCLK: 13, SWDIO: 12, RST: 11 } },
    ],
  },
  get_config_setup: { uart: true, i2c: false, spi: false, dap: true },
  get_config_function: {
    tcp: {
      enable: true,
      label: "透传服务",
      config: {
        port: 1346,
      },
      list: [{ ip: "192.168.3.100", port: 1346 }],
    },
    udp: {
      enable: false,
      label: "透传服务",
      config: {
        port: 6210,
      },
      list: [{ ip: "192.168.3.100", port: 6210 }],
    },
    udp2: {
      enable: false,
      label: "组播服务",
      config: {
        port: 8471,
        address: "238.84.84.71",
      },
      list: [{ ip: "192.168.3.100", port: 8471 }],
    },
  },
  get_config_wifi: {
    mode: 0,
    sta: {
      on: true,
      signal: -50,
      ssid: "TTG-MI4A",
      mac: "D4:DA:21:DC:8D:A2",
      ip: "192.168.31.204",
      gateway: "192.168.31.1",
      mask: "255.255.255.0",
      dns: "192.168.31.1",
      ip_mode: 1,
      dns_mode: 1,
      ip_config: {
        ip: "192.168.31.204",
        gateway: "192.168.31.1",
        mask: "255.255.255.0",
      },
      dns_config: "192.168.31.1",
    },
    ap: {
      on: false,
      ssid: "esp_tools",
      password: "12345678",
      ip: "192.168.4.1",
      mac: "D4:DA:21:DC:8D:A2",
      gateway: "192.168.4.1",
      mask: "255.255.255.0",
    },
  },
  set_config_setup: -1,
  set_config_io: 0,
  set_config_wakeup: -1,
  set_config_function: -1,
  wifi_connect: 0,
  wifi_mode: 0,
  wifi_config_sta: -1,
  wifi_config_ap: 0,
  get_files: function (req, clients) {
    let result_data = [
      { name: "test", type: 0, size: 0 },
      { name: "test.txt", type: 1, size: 0 },
      { name: "app.bin", type: 1, size: 0 },
      { name: "test.png", type: 1, size: 0 },
      { name: "test.svg", type: 1, size: 0 },
      { name: "test2.svg", type: 1, size: 0 },
    ];
    if (req.data.path == "/") result_data = [{ name: "www", type: 0 }];
    if (req.data.path == "/www/test")
      result_data = [{ name: "test.txt", type: 1, size: 0 }];
    clients.forEach((c) => {
      c.send(
        JSON.stringify({
          api: "get_files",
          data: result_data,
        })
      );
    });
  },
  create_folder: 0,
  get_files_search: [
    { name: "cache.html", type: 1, path: "/www/cache.html" },
    { name: "index.html.gz", type: 1, path: "/www/index.html.gz" },
  ],
  get_file: function (req, clients) {
    // let result_data = JSON.stringify({
    //   api: "get_file",
    //   data: { size: 0 },
    // });
    // clients.forEach((c) => {
    //   c.send(result_data);
    // });
    let file_name = null;
    if (req.data.path.indexOf(".txt") != -1) file_name = "./test.txt";
    if (req.data.path.indexOf(".svg") != -1) file_name = "./test.svg";
    if (req.data.path.indexOf(".png") != -1) file_name = "./test.png";
    if (req.data.path.indexOf(".bin") != -1) file_name = "./app.bin";
    if (!file_name)
      clients.forEach((c) => {
        c.send(
          JSON.stringify({
            api: "get_file",
            data: -1,
          })
        );
      });
    const stats = fs.statSync(file_name);
    let result_data = JSON.stringify({
      api: "get_file",
      data: { size: stats.size },
    });
    clients.forEach((c) => {
      c.send(result_data);
    });

    const readstream = fs.createReadStream(file_name);
    let i = 0;
    readstream.on("readable", () => {
      let file_data = readstream.read(4 * 1024);
      while (null !== file_data) {
        clients.forEach((c) => {
          c.send(file_data);
        });
        file_data = readstream.read(8192 * 1024);
      }
    });
  },
};

((Ws) => {
  const server = new Ws.Server({ port: 8080 });

  const init = () => {
    bindEvent();
  };

  function bindEvent() {
    server.on("open", handleOpen);
    server.on("close", handleClose);
    server.on("eror", handleError);
    server.on("connection", handleConnection);
  }

  function handleOpen() {
    console.log("WebSocket Open");
  }
  function handleClose() {
    console.log("WebSocket Close");
  }
  function handleError() {
    console.log("WebSocket Error");
  }
  function handleConnection(ws) {
    console.log("WebSocket Connection");
    ws.on("message", handleMessage);
  }

  function handleMessage(msg) {
    try {
      const data = JSON.parse(msg);
      console.log(data);
      for (let key in api_result) {
        if (data.api == key) {
          let result_data = null;
          if (typeof api_result[key] == "function") {
            api_result[key](data, server.clients);
          } else {
            result_data = JSON.stringify({ api: key, data: api_result[key] });
            server.clients.forEach((c) => {
              c.send(result_data);
            });
          }
          break;
        }
      }
    } catch (e) {
      console.log(msg, msg.length);
    }
  }

  init();
})(WebScorket);
